package com.scm.service.impl;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.scm.common.utils.DateUtils;
import com.scm.dto.resp.invent.QueryScmInventoryStashProductPageResp;
import com.scm.dto.resp.invent.ScmInventoryStashProductDo;
import com.scm.dto.resp.product.ScmProductDo;
import com.scm.persist.model.*;
import com.scm.persist.mybatis.ScmInventoryStashMapper;
import com.scm.persist.mybatis.ScmInventoryStashProductMapper;
import com.scm.service.IScmInventoryStashProductService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.scm.common.core.text.Convert;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

/**
 * 库存-仓库-商品信息Service业务层处理
 * 
 * @author reptilemanager
 * @date 2024-03-17
 */
@Slf4j
@Service
public class ScmInventoryStashProductServiceImpl implements IScmInventoryStashProductService
{
    @Autowired
    private ScmInventoryStashProductMapper scmInventoryStashProductMapper;

    @Autowired
    private ScmInventoryStashMapper scmInventoryStashMapper;


    @Autowired
    private ScmProductServiceImpl scmProductService;



    /**
     * 查询库存-仓库-商品信息
     * 
     * @param id 库存-仓库-商品信息主键
     * @return 库存-仓库-商品信息
     */
    @Override
    public ScmInventoryStashProduct selectScmInventoryStashProductById(Long id)
    {
        return scmInventoryStashProductMapper.selectByPrimaryKey(id);
    }

    /**
     * 查询库存-仓库-商品信息列表
     * 
     * @param scmInventoryStashProduct 库存-仓库-商品信息
     * @return 库存-仓库-商品信息
     */
    @Override
    public QueryScmInventoryStashProductPageResp selectScmInventoryStashProductList(ScmInventoryStashProduct scmInventoryStashProduct, Integer start, Integer size)
    {

        RowBounds rowBounds = new RowBounds(start,size);

        ScmInventoryStashProductExample example = new ScmInventoryStashProductExample();
        ScmInventoryStashProductExample.Criteria criteria = example.createCriteria();
        if(scmInventoryStashProduct.getStashId()!=null){
            criteria.andStashIdEqualTo(scmInventoryStashProduct.getStashId());
        }
        if(StringUtils.isNotEmpty(scmInventoryStashProduct.getProductCode())){
            criteria.andProductCodeEqualTo(scmInventoryStashProduct.getProductCode());
        }
        if(StringUtils.isNotEmpty(scmInventoryStashProduct.getProductName())){
            criteria.andProductNameLike(scmInventoryStashProduct.getProductName());
        }

        List<ScmInventoryStashProductDo> inventoryStashProductDoList = Lists.newArrayList();

        int count = scmInventoryStashProductMapper.countByExample(example);
        if(count>0){

            List<ScmInventoryStashProduct> list = scmInventoryStashProductMapper.selectByExampleWithRowbounds(example,rowBounds);
            if(!CollectionUtils.isEmpty(list)){
                for (ScmInventoryStashProduct inventoryStashProduct : list) {

                    ScmInventoryStash scmInventoryStash = scmInventoryStashMapper.selectByPrimaryKey(inventoryStashProduct.getStashId());
                    if(scmInventoryStash!=null){
                        inventoryStashProduct.setStashName(scmInventoryStash.getName());
                    }
                    ScmProductDo scmProductDo = scmProductService.selectScmProductById(inventoryStashProduct.getTenantId(),inventoryStashProduct.getProductId());


                    ScmInventoryStashProductDo inventoryStashProductDo = new ScmInventoryStashProductDo();
                    inventoryStashProductDo.setScmInventoryStashProduct(inventoryStashProduct,scmProductDo);
                    inventoryStashProductDoList.add(inventoryStashProductDo);
                }
            }
        }

        return QueryScmInventoryStashProductPageResp.builder().list(inventoryStashProductDoList).total(count).build();
    }

    /**
     * 新增库存-仓库-商品信息
     * 
     * @param scmInventoryStashProduct 库存-仓库-商品信息
     * @return 结果
     */
    @Override
    public int insertScmInventoryStashProduct(ScmInventoryStashProduct scmInventoryStashProduct)
    {
        return scmInventoryStashProductMapper.insertSelective(scmInventoryStashProduct);
    }

    /**
     * 修改库存-仓库-商品信息
     * 
     * @param scmInventoryStashProduct 库存-仓库-商品信息
     * @return 结果
     */
    @Override
    public int updateScmInventoryStashProduct(ScmInventoryStashProduct scmInventoryStashProduct)
    {
        return scmInventoryStashProductMapper.updateByPrimaryKey(scmInventoryStashProduct);
    }

    /**
     * 批量删除库存-仓库-商品信息
     * 
     * @param ids 需要删除的库存-仓库-商品信息主键
     * @return 结果
     */
    @Override
    public int deleteScmInventoryStashProductByIds(String ids)
    {
//        return scmInventoryStashProductMapper.deleteScmInventoryStashProductByIds(Convert.toStrArray(ids));
        return 1;
    }

    /**
     * 删除库存-仓库-商品信息信息
     * 
     * @param id 库存-仓库-商品信息主键
     * @return 结果
     */
    @Override
    public int deleteScmInventoryStashProductById(Long id)
    {
        return scmInventoryStashProductMapper.deleteByPrimaryKey(id);
    }

    @Transactional
    @Override
    public int saveStashProduct(Long tenantId,ScmInventoryInDetail scmInventoryInDetail) {

        ScmInventoryStashProductExample example = new ScmInventoryStashProductExample();
        example.createCriteria().andStashIdEqualTo(scmInventoryInDetail.getStashId()).andProductIdEqualTo(scmInventoryInDetail.getProductId());
        List<ScmInventoryStashProduct>  list =  scmInventoryStashProductMapper.selectByExample(example);

        if(CollectionUtils.isEmpty(list)){
            ScmInventoryStashProduct scmInventoryStashProduct = new ScmInventoryStashProduct();
            scmInventoryStashProduct.setTenantId(tenantId);
            scmInventoryStashProduct.setStashId(scmInventoryInDetail.getStashId());
            scmInventoryStashProduct.setStashName(scmInventoryInDetail.getStashName());
            scmInventoryStashProduct.setProductId(scmInventoryInDetail.getProductId());
            scmInventoryStashProduct.setProductCode(scmInventoryInDetail.getProductCode());
            scmInventoryStashProduct.setProductName(scmInventoryInDetail.getProductName());
            scmInventoryStashProduct.setProductCount(scmInventoryInDetail.getProductCount());
            scmInventoryStashProduct.setProductUnit(scmInventoryInDetail.getProductUnit());
            scmInventoryStashProduct.setProductSpec(scmInventoryInDetail.getProductSpec());
            scmInventoryStashProduct.setInStashAmount(scmInventoryInDetail.getInStashAmount());
            scmInventoryStashProduct.setOutStashAmount(scmInventoryInDetail.getSettleAmount());

            int i = scmInventoryStashProductMapper.insertSelective(scmInventoryStashProduct);
            if(i==0){
                throw new RuntimeException("库存更新失败，请重试或联系系统管理员");
            }
        }else{

            ScmInventoryStashProduct scmInventoryStashProduct = list.get(0);
            scmInventoryStashProduct.setProductCount(scmInventoryStashProduct.getProductCount()+scmInventoryInDetail.getProductCount());
            scmInventoryStashProduct.setVersions(scmInventoryStashProduct.getVersions()+1);
            example = new ScmInventoryStashProductExample();
            example.createCriteria().andVersionsEqualTo(scmInventoryStashProduct.getVersions()).andIdEqualTo(scmInventoryStashProduct.getId());
            int i = scmInventoryStashProductMapper.updateByExampleSelective(scmInventoryStashProduct,example);
            if(i==0){
                throw new RuntimeException("库存更新失败，请重试或联系系统管理员");
            }
        }

        return 1;
    }

    @Transactional
    @Override
    public int saveStashProductByOut(Long tenantId,ScmInventoryOutDetail scmInventoryOutDetail) {

        ScmInventoryStashProduct inventoryStashProduct =  scmInventoryStashProductMapper.selectByPrimaryKey(scmInventoryOutDetail.getStashProductId());

        if(inventoryStashProduct==null){
            throw new RuntimeException("库存数据异常，请联系系统管理员");
        }else{

            inventoryStashProduct.setProductCount(scmInventoryOutDetail.getProductCount()-scmInventoryOutDetail.getProductCount());
            inventoryStashProduct.setProductLockCount(inventoryStashProduct.getProductLockCount()-scmInventoryOutDetail.getProductCount());
            inventoryStashProduct.setVersions(inventoryStashProduct.getVersions()+1);
            ScmInventoryStashProductExample example = new ScmInventoryStashProductExample();
            example.createCriteria().andVersionsEqualTo(inventoryStashProduct.getVersions()).andIdEqualTo(inventoryStashProduct.getId());

            int i = scmInventoryStashProductMapper.updateByExampleSelective(inventoryStashProduct,example);
            if(i==0){
                throw new RuntimeException("库存更新失败，请重试或联系系统管理员");
            }
        }
        return 1;
    }

    @Override
    public ScmInventoryStashProductDo getStashProductById(long id) {

        ScmInventoryStashProduct inventoryStashProduct = scmInventoryStashProductMapper.selectByPrimaryKey(id);

        ScmInventoryStashProductDo inventoryStashProductDo = new ScmInventoryStashProductDo();

        ScmProductDo scmProductDo = scmProductService.selectScmProductById(inventoryStashProduct.getTenantId(),inventoryStashProduct.getProductId());

        inventoryStashProductDo.setScmInventoryStashProduct(inventoryStashProduct,scmProductDo);

        if(inventoryStashProduct.getStashId()!=null){
            ScmInventoryStash scmInventoryStash = scmInventoryStashMapper.selectByPrimaryKey(inventoryStashProduct.getStashId());
            if(scmInventoryStash!=null){
                inventoryStashProductDo.setStashName(scmInventoryStash.getName());
            }
        }

        return inventoryStashProductDo;
    }



    @Transactional
    @Override
    public String  lockStashProductByUpdate(List<ScmInventoryOutDetail> oldList,List<ScmInventoryOutDetail> updatelist){

        String msg = "1";

        if(CollectionUtils.isEmpty(updatelist)){
            return "";
        }

        Map<Long, ScmInventoryOutDetail> oldStashProductIdMap = oldList.stream()
                .collect(Collectors.toMap(ScmInventoryOutDetail::getStashProductId, e -> e));


        for (ScmInventoryOutDetail scmInventoryOutDetail : updatelist) {

            ScmInventoryStashProduct inventoryStashProduct = scmInventoryStashProductMapper.selectByPrimaryKey(scmInventoryOutDetail.getStashProductId());


            int productLockCount = inventoryStashProduct.getProductLockCount()==null?0:inventoryStashProduct.getProductLockCount();

            int availableCount = inventoryStashProduct.getProductCount()-productLockCount;

            int oldProductCount = 0;
            ScmInventoryOutDetail oldInventoryOutDetail = oldStashProductIdMap.get(scmInventoryOutDetail.getStashProductId());
            if(oldInventoryOutDetail!=null){
                availableCount +=oldInventoryOutDetail.getProductCount();
                oldProductCount = oldInventoryOutDetail.getProductCount();
            }

            if(scmInventoryOutDetail.getProductCount()>availableCount){
                //出错 库存不够
                msg="id为"+inventoryStashProduct.getId()+"的商品（"+inventoryStashProduct.getProductName()+"）库存不足，实际可用库存："+availableCount;
                throw new RuntimeException(msg);
            }
            else{
                inventoryStashProduct.setProductLockCount(productLockCount+scmInventoryOutDetail.getProductCount()-oldProductCount);
                ScmInventoryStashProductExample example = new ScmInventoryStashProductExample ();
                example.createCriteria().andIdEqualTo(inventoryStashProduct.getId()).andVersionsEqualTo(inventoryStashProduct.getVersions());
                inventoryStashProduct.setVersions(inventoryStashProduct.getVersions()+1);
                int i = scmInventoryStashProductMapper.updateByExampleSelective(inventoryStashProduct,example);
                if(i==0){
                    //更新失败，锁生效，回滚相关操作
                    msg="id为"+inventoryStashProduct.getId()+"的商品（"+inventoryStashProduct.getProductName()+"）更新库存失败，可能是因为库存可用余额发生变更导致，请确认库存余额后重新发起操作";
                    throw new RuntimeException(msg);
                }

            }
        }

        return msg;
    }

    @Override
    public List<ScmInventoryStashProduct> queryListByProductIds(Long tenantId, List<Long> productIds) {

        if(CollectionUtils.isEmpty(productIds)){
            return Lists.newArrayList();
        }
        ScmInventoryStashProductExample example = new ScmInventoryStashProductExample();
        example.createCriteria().andTenantIdEqualTo(tenantId).andProductIdIn(productIds);

        return scmInventoryStashProductMapper.selectByExample(example);

    }

    //锁库存
    @Transactional
    @Override
    public String lockStashProductByInsert(List<ScmInventoryOutDetail> list) {
        String msg = "1";

        if(CollectionUtils.isEmpty(list)){
            return "";
        }

        for (ScmInventoryOutDetail scmInventoryOutDetail : list) {

            ScmInventoryStashProduct inventoryStashProduct = scmInventoryStashProductMapper.selectByPrimaryKey(scmInventoryOutDetail.getStashProductId());

            int productLockCount = inventoryStashProduct.getProductLockCount()==null?0:inventoryStashProduct.getProductLockCount();

            int availableCount = inventoryStashProduct.getProductCount()-productLockCount;

            if(scmInventoryOutDetail.getProductCount()>availableCount){
                //出错 库存不够
                msg="id为"+inventoryStashProduct.getId()+"的商品（"+inventoryStashProduct.getProductName()+"）库存不足，实际可用库存："+availableCount;
                throw new RuntimeException(msg);
            }
            else{
                inventoryStashProduct.setProductLockCount(productLockCount+scmInventoryOutDetail.getProductCount());
                ScmInventoryStashProductExample example = new ScmInventoryStashProductExample ();
                example.createCriteria().andIdEqualTo(inventoryStashProduct.getId()).andVersionsEqualTo(inventoryStashProduct.getVersions());
                inventoryStashProduct.setVersions(inventoryStashProduct.getVersions()+1);
                int i = scmInventoryStashProductMapper.updateByExampleSelective(inventoryStashProduct,example);
                if(i==0){
                    //更新失败，锁生效，回滚相关操作
                    msg="id为"+inventoryStashProduct.getId()+"的商品（"+inventoryStashProduct.getProductName()+"）更新库存失败，可能是因为库存可用余额发生变更导致，请确认库存余额后重新发起操作";
                    throw new RuntimeException(msg);
                }
            }
        }

        return msg;
    }




}
